import math
import pygame
import helpers

MAX_JOYSTICK = 255;

class Gamepad:
	def __init__(self, joystickID, left, top):
		# Dimensions
		self.TEXT_SIZE = 26
		self.TOP = top
		self.LEFT = left
		self.BUTTONS_X = 128 + self.LEFT
		self.BUTTONS_Y = 200 + self.TOP
		self.HAT_X = 48 + self.LEFT
		self.HAT_Y = 192 + self.TOP
		self.BUTTON_WIDTH = 32
		self.BUTTON_SPACING = 16
		self.RADIUS = 80
		self.WIDTH = 416
		self.HEIGHT = 304
		self.JOYSTICK0_CENTER = (112,96)
		self.JOYSTICK1_CENTER = (304,96)

		# Shapes and Colors
		self.BLACK	= (0x00, 0x00, 0x00)
		self.WHITE	= (0xFF, 0xFF, 0xFF)
		
		# Initialize the bounding box rectangle
		self.BoundingBox = pygame.Rect(self.LEFT, self.TOP, self.WIDTH, self.HEIGHT)
	
		# Initialize the joystick
		self.joystick = pygame.joystick.Joystick(joystickID)
		self.joystick.init()
		
		# Prepare the hat rects
		self.hatRects = (	pygame.Rect(self.HAT_X, self.HAT_Y-2, self.BUTTON_WIDTH, self.BUTTON_WIDTH),
							pygame.Rect(self.HAT_X+self.BUTTON_WIDTH+2, self.HAT_Y+self.BUTTON_WIDTH, self.BUTTON_WIDTH, self.BUTTON_WIDTH),
							pygame.Rect(self.HAT_X, self.HAT_Y+2*self.BUTTON_WIDTH+2, self.BUTTON_WIDTH, self.BUTTON_WIDTH),
							pygame.Rect(self.HAT_X-self.BUTTON_WIDTH-2, self.HAT_Y+self.BUTTON_WIDTH, self.BUTTON_WIDTH, self.BUTTON_WIDTH)	)
		
		# Prepare the buttons array and buttonRects list
		self.buttonRects = list()
		self.numButtons = self.joystick.get_numbuttons()
		for i in xrange(self.numButtons):
			if i == 0:
				self.buttonRects.insert(i, pygame.Rect(self.BUTTONS_X, self.BUTTONS_Y, self.BUTTON_WIDTH, self.BUTTON_WIDTH))
			elif i < 6:
				self.buttonRects.insert(i, pygame.Rect(self.buttonRects[i-1].left+self.BUTTON_WIDTH+self.BUTTON_SPACING, self.BUTTONS_Y, self.BUTTON_WIDTH, self.BUTTON_WIDTH))
			elif i == 6:
				self.buttonRects.insert(i, pygame.Rect(self.BUTTONS_X, self.BUTTONS_Y+self.BUTTON_SPACING+self.BUTTON_WIDTH,self.BUTTON_WIDTH, self.BUTTON_WIDTH))
			else:
				self.buttonRects.insert(i, pygame.Rect(self.buttonRects[(i-1)%6].left+self.BUTTON_WIDTH+self.BUTTON_SPACING, self.BUTTONS_Y+self.BUTTON_SPACING+self.BUTTON_WIDTH,self.BUTTON_WIDTH, self.BUTTON_WIDTH))
		self.buttons = [0]*self.numButtons
		
		# Initialize the gamepad parameters
		self.hat = (0,0)
		
		self.x0 = 0
		self.y0 = 0
		self.rad0 = 0
		
		self.x1 = 0
		self.y1 = 0
		self.rad1 = 0
		
		# Initialize the font we'll be using
		pygame.font.init()
		self.font = pygame.font.Font('CRYSRG__.TTF',self.TEXT_SIZE)

	def compute(self):
		# Get the joystick positions
		self.x0 = self.joystick.get_axis(0)
		self.y0 = self.joystick.get_axis(1)
		self.x1 = self.joystick.get_axis(2)
		self.y1 = self.joystick.get_axis(3)

		# Calculate the radii/angles for this x,y position
		self.rad0 = math.hypot(self.x0,self.y0)
		self.rad0 = helpers.limitToRange(self.rad0,0,1)
		self.ang0 = math.atan2(self.y0,self.x0)
		self.drawX0 = self.rad0*math.cos(self.ang0)
		self.drawY0 = self.rad0*math.sin(self.ang0)
		
		self.rad1 = math.hypot(self.x1,self.y1)
		self.rad1 = helpers.limitToRange(self.rad1,0,1)
		self.ang1 = math.atan2(self.y1,self.x1)
		self.drawX1 = self.rad1*math.cos(self.ang1)
		self.drawY1 = self.rad1*math.sin(self.ang1)
		
		#'clicks' to middle
		"""tab = .12
		if -tab < self.x < tab:
			self.x = 0
		if -tab < self.y < tab:
			self.y = 0"""
			
		# Update the hat state
		self.hat = self.joystick.get_hat(0)
		
		# Update the button states
		for i in xrange(self.numButtons):
			self.buttons[i] = self.joystick.get_button(i)

	def draw(self,surface):
		# Draw the Bounding Box
		pygame.draw.rect(surface, self.BLACK, self.BoundingBox, 2)
		
		# Print out the hat
		## Start with the simplest case: no hats pressed
		pygame.draw.rect(surface,self.BLACK,self.hatRects[0],2)
		pygame.draw.rect(surface,self.BLACK,self.hatRects[1],2)
		pygame.draw.rect(surface,self.BLACK,self.hatRects[2],2)
		pygame.draw.rect(surface,self.BLACK,self.hatRects[3],2)
		## Modify if necessary
		### x-axis
		if self.hat[0] < 0:
			pygame.draw.rect(surface,self.BLACK,self.hatRects[3])
		elif self.hat[0] > 0:
			pygame.draw.rect(surface,self.BLACK,self.hatRects[1])
		### y-axis
		if self.hat[1] < 0:
			pygame.draw.rect(surface,self.BLACK,self.hatRects[2])
		elif self.hat[1] > 0:
			pygame.draw.rect(surface,self.BLACK,self.hatRects[0])
		

		# Print out all the buttons
		for i in xrange(self.numButtons):
			if self.buttons[i]:
				textColor = self.WHITE
				bgColor = self.BLACK
				pygame.draw.rect(surface,self.BLACK,self.buttonRects[i])
			else:
				textColor = self.BLACK
				bgColor = self.WHITE
				pygame.draw.rect(surface,self.BLACK,self.buttonRects[i], 2)
			
			text = self.font.render(str(i),1,textColor,bgColor)
			surface.blit(text,text.get_rect(centerx=self.buttonRects[i].left+16,centery=self.buttonRects[i].top+16))
				
				
		"""textPosition = h-32
		for i in xrange(self.numButtons):
			if self.buttons[i]:
				color = (0,255,0)	# 0x00FF00
			else:
				color = (64,0,64)	# 0x400040
			text = self.font.render(str(i),1,color)
			surface.blit(text,text.get_rect(centerx=w*(i+1)/(self.numButtons+1),centery=textPosition))"""
		
		# Draw the joystick positions
		arrowX0 = int(round(self.JOYSTICK0_CENTER[0]+self.LEFT+self.drawX0*self.RADIUS))
		arrowY0 = int(round(self.JOYSTICK0_CENTER[1]+self.TOP+self.drawY0*self.RADIUS))
		pygame.draw.aaline(surface,self.BLACK,(self.JOYSTICK0_CENTER[0]+self.LEFT,self.JOYSTICK0_CENTER[1]+self.TOP),(arrowX0,arrowY0),1)
		pygame.draw.circle(surface,self.BLACK,(arrowX0,arrowY0),8,4)
		pygame.draw.circle(surface,self.BLACK,(self.JOYSTICK0_CENTER[0]+self.LEFT,self.JOYSTICK0_CENTER[1]+self.TOP),self.RADIUS,2)
		
		arrowX1 = int(round(self.JOYSTICK1_CENTER[0]+self.LEFT+self.drawX1*self.RADIUS))
		arrowY1 = int(round(self.JOYSTICK1_CENTER[1]+self.TOP+self.drawY1*self.RADIUS))
		pygame.draw.aaline(surface,self.BLACK,(self.JOYSTICK1_CENTER[0]+self.LEFT,self.JOYSTICK1_CENTER[1]+self.TOP),(arrowX1,arrowY1),1)
		pygame.draw.circle(surface,self.BLACK,(arrowX1,arrowY1),8,4)
		pygame.draw.circle(surface,self.BLACK,(self.JOYSTICK1_CENTER[0]+self.LEFT,self.JOYSTICK1_CENTER[1]+self.TOP),self.RADIUS,2)

		
			
		
		
